#ifndef TRANSFORMERCONTENTCONSTRUCTPATH_HPP_3
#define TRANSFORMERCONTENTCONSTRUCTPATH_HPP_3

#include "logger.hpp"
#include "transContentDefine.h"
#include "transContentErrorCode.h"

class transContentConstructPath{
	private:
		int localPort;
		NodeAddr target;
		int timeout;
		int canDelete;

		int getFixedPathResult;
		int pathType;
		int pathLen;
		char path[44];

		pthread_mutex_t waitMutex;
		pthread_cond_t waitCond;

	public:
		transContentConstructPath(): localPort(0), timeout(INT_MAX), canDelete(0), getFixedPathResult(0), pathType(FIXED_PATH_TYPE_ERROR),pathLen(0), waitMutex(PTHREAD_MUTEX_INITIALIZER), waitCond(PTHREAD_COND_INITIALIZER){debug_enter();}

		int getLocalPort() const{
			return localPort;			
		}

		void setLocalPort(int localPort){
			this->localPort = localPort;
		}

		NodeAddr getTarget() const{
			return target;
		}

		void setTarget(const NodeAddr* target){
			this->target = *target;
		}

		int getTimeout() const{
			return timeout;
		}

		/////////////////////////////////
		/// now this method has no function
		/////////////////////////////////
		void setTimeout(int timeout){
		//	this->timeout = timeout;
		}

		int getCanBeDeleted() const{
			return canDelete;
		}

		///////////////////////////////////////////////////////
		/// not block the caller, just send a buffer to stack, the stack add the request to connect pathManager
		/// only this function method use regist fifo
		///
		/// parameter:
		///		E_TRANC_SUCESS: always return this method
		///////////////////////////////////////////////////////
		int contructPath(){
			debug_enter();
			return constructAndSendPacket(message_type_inner_functionCall_constructSeq_request);
		}

		////////////////////////////////////////////////////////////////////////
		/// only response the get fixed path request, not construct path
		/// now get fixed path, will not let the connect layer to create a new fixed path, if not exist, just return failed, or return sucess, with the fixed path return
		///
		/// suggest call this method before start to send data use fixed path
		/////////////////////////////////////////////////////////////////////////
		int response();

		int getFixedPath(void* buffer, int len, int* pathType){
			debug_enter();
			constructAndSendPacket(message_type_inner_functionCall_getFixedPathRequest);

			// wait stack response
			pthread_mutex_lock(&waitMutex);
			pthread_cond_wait(&waitCond, &waitMutex);
			pthread_mutex_unlock(&waitMutex);
			if(getFixedPathResult == 0){
				canDelete = 1;
				log_error("get fixed path from stack error");
				return getFixedPathResult;
			}
			*pathType = this->pathType;
			memcpy(buffer, this->path, this->pathLen);
			canDelete = 1;
			return this->pathLen;
		}

	private:
		int constructAndSendPacket(int messageType){
			debug_enter();
            static char buffer[20]={0};
            memset(buffer, 0x00, 20);

            // set packet length
            *((short*)buffer) = 16; 
            buffer[2] = (char)messageType;
			*(int*(buffer+4)) = localPort;
            *(NodeAddr*(buffer+8)) = target;

            // send to stack
            TransContentDispatcher::getInstance()->sendDataRegistToStack(buffer, 16);
            debug_leave();
			return E_TRANC_SUCESS;
		}
};
#endif //TRANSFORMERCONTENTCONSTRUCTPATH_HPP_3
